package juf.adapter;



import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import java.util.Collection;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;


import juf.Property;
import juf.ui.JufForm;

/**Binding between a JList component and a Property data source 
 * 
 * This is a read-only control, but it could be extended to bind to a field or method. 
 * 
 * TODO could we make this so when the user double-clicks an object, he can edit it in a new jufform?
 * 
 * @author Dale Halliwell
 */

@SuppressWarnings("serial")
public class JListAdapter extends AbstractAdapter implements Adapter {

	private Vector<Object> listitems = new Vector<Object>(); //holds the actual objects referred to by the index of the list, 

	private JList listcomponent; //so can be accessed by getDataComponent()
	
	/**Create a new JListAdapter, bound to a property and containing listData
	 * @param property the Property to bind to, representing either a Collection or an Array type
	 */
	@SuppressWarnings("unchecked")
	public JListAdapter(Property property) { 
		
		//depending whether it is being bound to a collection or to an array
		//load the selections into the list
		if (property.getValue() instanceof Collection) {
			listitems.addAll(((Collection) property.getValue()));	
		}	
		else if (property.getValue() instanceof Object[]){
			for(Object o : ((Object[])property.getValue())){ //add all objects to the list
				if (o != null)
					listitems.add(o); //only add array elements that are not null
			}
		}
		else
			throw new IllegalArgumentException();
		
		//set the datasource of the list to be our vector
		this.listcomponent = new JList(listitems);
		this.component = new JScrollPane(listcomponent); //the abstract component is actually the scrollpane containing the list		
		this.component.setPreferredSize(new Dimension(300,100));
		this.listcomponent.setPreferredSize(new Dimension(300,100));
		bind(property, new Dimension(350,100));
		
		//listen for doubleclicks on the list
		this.listcomponent.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent e) {
		        if (e.getClickCount() == 2 && ((JList) listcomponent).getSelectedIndex() >= 0) {
		        	System.out.println("Opening: " + listitems.get((((JList) listcomponent).getSelectedIndex())).toString());
		        	//open a JufForm in a new window to edit that object
		        	JufForm jufForm = new JufForm(listitems.get((((JList) listcomponent).getSelectedIndex())));
					JFrame popup = new JFrame("JufForm"); //create the window frame
					popup.getContentPane().add(jufForm); 
					popup.pack(); //resize the window to suit the JufForm
					popup.setVisible(true); //show the window
		        	//that JufForm should callback a function in JListAdapter that updates the list
		         }
		    }
		});
	}
	
	/* (non-Javadoc)
	 * @see adapters.Adapter#refresh()
	 */
	@Override
	public void refresh() {
		if (!(property.getValue() == null))
			((JList)listcomponent).setSelectedValue(property.getValue(), true); //true = force the list to scroll to the new selection
	}

	/* (non-Javadoc)
	 * @see adapters.Adapter#save()
	 */
	@Override
	public void save() {
		//just redisplay the control, updating from the object. 
		//any changes to the object will have been
		//saved by the jufform that was created around it
		refresh();
	}
	
	@Override
	public Component getDataComponent(){
		return listcomponent;
	}

}
